﻿using Fiddler;
using FiddlerExUtils.Tools;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FiddlerInspectorsEx
{
    public class Configuration
    {
        private Process p;
        private int reqTimeOut = FiddlerApplication.Prefs.GetInt32Pref("fiddlerex.func.timeout", 3000);
        // 插件检测更新url
        private string updateCheckUrl = FiddlerApplication.Prefs.GetStringPref("fiddlerex.urlconfig.updatecheckurl", "");
        private string updateCheckFile = "";
        private string forceUpdate = "0";
        private int clearLogDays = 7;
        private string releaseLog = "";
        private string pluginVersion = "";

        ///<summary>
        ///启用插件时，加载配置
        /// </summary>
        public void LoadConfig()
        {
            try
            {
                Registry.SetValue("HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", "Fiddler.exe", 8888); //8888, IE11:11001

                //获取json配置并更新本地Preferences配置
                string jsonConfig = LoadJsonConfig();
                //FiddlerApplication.Log.LogString("插件配置获取成功：" + jsonConfig);

                reqTimeOut = Convert.ToInt16(CommonFunction.GetJsonValueWithPath(jsonConfig, "requestTimeout"));
                FiddlerApplication.Prefs.SetInt32Pref("fiddlerex.func.timeout", reqTimeOut);
                updateCheckUrl = CommonFunction.GetJsonValueWithPath(jsonConfig, "updateCheckUrl");
                updateCheckFile = CommonFunction.GetJsonValueWithPath(jsonConfig, "updateCheckFile");
                FiddlerApplication.Prefs.SetStringPref("fiddlerex.urlconfig.updatecheckurl", updateCheckUrl);
                forceUpdate = CommonFunction.GetJsonValueWithPath(jsonConfig, "forceUpdate");
                clearLogDays = Convert.ToInt16(CommonFunction.GetJsonValueWithPath(jsonConfig, "clearLogDays"));
                releaseLog = CommonFunction.GetJsonValueWithPath(jsonConfig, "releaseLog");
                pluginVersion = CommonFunction.GetJsonValueWithPath(jsonConfig, "pluginVersion");
            }
            catch (Exception e)
            {
                FiddlerApplication.Log.LogString("LoadConfig: " + e.Message);
            }

        }

        ///<summary>
        ///从服务器获取Json格式数据配置
        /// </summary>
        public string LoadJsonConfig()
        {
            try
            {
                string result = "";
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(updateCheckUrl);
                req.Method = "GET";
                req.ContentType = "application/json;charset=utf-8";
                req.Timeout = reqTimeOut;
                req.Proxy = null;

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                Stream stream = resp.GetResponseStream();
                //获取响应内容  
                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                {
                    result = reader.ReadToEnd();
                }
                resp.Close();
                return result;

            }
            catch (Exception ex)
            {
                FiddlerApplication.Log.LogString("LoadJsonConfig：" + updateCheckUrl);
                return "";
            }
        }

        /// <summary>
        /// 检测插件更新
        /// </summary>
        /// <param name="isCustomCheck">是否手动检查更新</param>
        public void FiddlerUpdateCheck(bool isCustomCheck)
        {
            //升级提醒间隔天数
            int checkDays = 7;
            if (forceUpdate == "0" && !isCustomCheck)
            {
                string updateCheckDate = FiddlerApplication.Prefs.GetStringPref("fiddlerex.urlconfig.updatecheckdate", "2022-12-15");
                int compNum = DateTime.Now.Subtract(DateTime.Parse(updateCheckDate)).Days;
                if (compNum <= checkDays)
                {
                    return;
                }
            }
            // 插件检测更新
            string checkurl = "";
            string releaseLogStr = "";
            Version currentVersion = null;
            Version lastVersion = null;
            string pluginName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
            if (updateCheckFile != "")
            {
                try
                {
                    lastVersion = new Version(pluginVersion);
                    currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

                    if (lastVersion > currentVersion)
                    {
                        releaseLogStr = pluginName + " v" + pluginVersion + "\n" + releaseLog;

                        checkurl = updateCheckFile.Replace(' ', '#');
                    }
                }
                catch (Exception e)
                {
                    FiddlerApplication.Log.LogString(updateCheckFile + " 文件不存在");
                    if (isCustomCheck)
                    {
                        MessageBox.Show(updateCheckFile + " 文件不存在！", "更新提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    return;
                }

                if (checkurl != "")
                {
                    new Thread(
                          delegate ()
                          {
                              Thread.Sleep(5000);
                              DialogResult dr = DialogResult.Yes;
                              FiddlerApplication.Log.LogString(pluginName + " 有新版本：\n" + releaseLogStr);
                              if (forceUpdate == "0")
                              {
                                  dr = MessageBox.Show(releaseLogStr + "\n\n" + pluginName + " 有新版本，是否下载并安装？\n选择[否]，则" + checkDays + "天内不再提醒。", "插件升级提示 v" + currentVersion.ToString() + " --> v" + lastVersion.ToString(), MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                                  if (dr == DialogResult.Yes)
                                  {
                                      try
                                      {
                                          p = new System.Diagnostics.Process();
                                          p.StartInfo.FileName = CommonFunction.GetFiddlerExBinDirectory() + "FiddlerExUpdate.exe";
                                          p.StartInfo.Arguments = checkurl + " " + forceUpdate + " " + lastVersion;
                                          p.Start();
                                      }
                                      catch (Exception ee)
                                      {
                                          FiddlerApplication.Log.LogString(CommonFunction.GetFiddlerExBinDirectory() + "FiddlerExUpdate.exe");
                                      }
                                  }
                                  else if (dr == DialogResult.No)
                                  {
                                      FiddlerApplication.Prefs.SetStringPref("fiddlerex.urlconfig.updatecheckdate", DateTime.Now.ToString("yyyy-MM-dd"));
                                      FiddlerApplication.Log.LogString(checkDays + "天之后再提醒插件版本升级。");
                                  }
                              }
                              else
                              {
                                  try
                                  {
                                      p = new System.Diagnostics.Process();
                                      p.StartInfo.FileName = CommonFunction.GetFiddlerExBinDirectory() + "FiddlerExUpdate.exe";
                                      p.StartInfo.Arguments = checkurl + " " + forceUpdate + " " + lastVersion;
                                      p.Start();
                                  }
                                  catch (Exception ee)
                                  {
                                      FiddlerApplication.Log.LogString(CommonFunction.GetFiddlerExBinDirectory() + "FiddlerExUpdate.exe");
                                  }
                              }
                          }).Start();

                }
                else
                {
                    FiddlerApplication.Log.LogString(pluginName + " 已是最新版本：v" + currentVersion.ToString());
                    if (isCustomCheck)
                    {
                        MessageBox.Show(pluginName + " 已是最新版本：v" + currentVersion.ToString(), "更新提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
            else
            {
                FiddlerApplication.Log.LogString("Fiddler插件更新地址updateCheckUrl为空！");
                if (isCustomCheck)
                {
                    MessageBox.Show("Fiddler插件更新地址updateCheckUrl为空！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        /// <summary>
        /// 检测Fiddler设置
        /// </summary>
        public void FiddlerSettingsCheck()
        {
            try
            {
                new Thread(
                        delegate ()
                        {
                            Thread.Sleep(3000);
                            bool continueCheck = false;
                            //检测Fiddler CA证书
                            if (!CertMaker.rootCertIsTrusted())
                            {
                                MessageBox.Show("如需抓取HTTPS协议包，请先安装Fiddler CA证书\n注：FireFox浏览器需手动导入Fiddler CA证书", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                CertMaker.createRootCert();
                                CertMaker.trustRootCert();
                                if (!CertMaker.rootCertIsTrusted())
                                {
                                    MessageBox.Show("未安装Fiddler CA证书", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                    continueCheck = false;
                                }
                                else
                                {
                                    MessageBox.Show("如需手机端APP HTTPS抓包，请手机端浏览器访问" + GetLocalIP() + ":" + CONFIG.ListenPort + "(默认端口)，下载并安装Fiddler证书（Android不能安装的，手机设置凭据里可从SD卡导入安装）\n注：iOS10及以上系统，安装成功后：设置 > 通用 > 关于本机 > 证书信任设置，须打开此证书开关才能抓包", "友情提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                    continueCheck = true;
                                }
                            }
                            else
                            {
                                continueCheck = true;
                            }

                            if (continueCheck)
                            {
                                //检测HTTPS
                                if (!CONFIG.bCaptureCONNECT)
                                {
                                    CONFIG.bCaptureCONNECT = true;
                                }
                                try
                                {
                                    if (!CONFIG.DecryptHTTPS)
                                    {
                                        CONFIG.DecryptHTTPS = true;
                                    }
                                }
                                catch (Exception e)
                                {
                                    //老版兼容
                                    if (!CONFIG.bMITM_HTTPS)
                                    {
                                        CONFIG.bMITM_HTTPS = true;
                                    }
                                    FiddlerApplication.Log.LogString("FiddlerSettingsCheck" + e.Message);
                                }
                                CONFIG.IgnoreServerCertErrors = true;
                                //检测远程连接
                                if (!CONFIG.bAllowRemoteConnections)
                                {
                                    MessageBox.Show("手机端抓包，请勾选[Allow remote computers to connect]\n点击[OK]保存后请重启Fiddler\nPath: Tools > Options > Connections", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                    FiddlerApplication.UI.actShowOptions("Connections");
                                }
                            }
                        }).Start();
            }
            catch (Exception)
            {

            }
        }
        /// <summary>
        /// Fiddler证书生成器
        /// </summary>
        public void FiddlerCertMakerInstall()
        {
            try
            {
                Process p = new System.Diagnostics.Process();
                p.StartInfo.FileName = CommonFunction.GetFiddlerExBinDirectory() + "fiddlercertmaker.exe";
                p.Start();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        /// <summary>
        /// 清理X天之前的log文件
        /// </summary>
        public void FiddlerLogClear()
        {
            if (clearLogDays > 0)
            {
                new Thread(
                        delegate ()
                        {
                            string[] paths = new string[3];
                            paths[0] = CommonFunction.GetFiddlerExCompareDirectory();
                            paths[1] = CommonFunction.GetFiddlerExExportDirectory();
                            paths[2] = CommonFunction.GetFiddlerExLogDirectory();
                            foreach (string path in paths)
                            {
                                try
                                {
                                    DirectoryInfo dir = new DirectoryInfo(path);
                                    foreach (FileInfo f in dir.GetFiles("*.*", SearchOption.TopDirectoryOnly))
                                    {
                                        if (DateTime.Now.Subtract(f.CreationTime).Days > clearLogDays)
                                        {
                                            f.Delete();
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                    FiddlerApplication.Log.LogString("FiddlerLogClear: " + e.Message);
                                }
                            }
                        }).Start(); 
            }
        }
        /// <summary>
        /// 获取本机IP
        /// </summary>
        /// <returns></returns>
        public string GetLocalIP()
        {
            try
            {
                string HostName = Dns.GetHostName(); //得到主机名
                IPHostEntry IpEntry = Dns.GetHostEntry(HostName);
                string ipv4 = "";
                for (int i = 0; i < IpEntry.AddressList.Length; i++)
                {
                    //从IP地址列表中筛选出IPv4类型的IP地址
                    //AddressFamily.InterNetwork表示此IP为IPv4,
                    //AddressFamily.InterNetworkV6表示此地址为IPv6类型
                    if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
                    {
                        ipv4 = IpEntry.AddressList[i].ToString();
                        break;
                    }
                }
                return ipv4;
            }
            catch (Exception ex)
            {
                FiddlerApplication.Log.LogString("获取本机IP出错:" + ex.Message);
                return "";
            }
        }
    }
}
